﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace DELVE_GAME.ViewStructure
{
    class PlayStage : Stage
    {
        //int state;
        String infoString = "";
        UpgradeMenuComposite upgradeMenu;
        GameboardComponent gameboard;
        Tile selectedTile;
        List<GameboardCell> selectedCells;
        View view;
        public Rectangle selectionBox;
        MouseState ms;
        MouseState prevMs;
        Texture2D selectionLine;
        bool isDragging;
        Game game;
        TextComponent timerText;

        public PlayStage(UpgradeMenuComposite upgradeMenu, View view, Texture2D selectRect, Game game)
        {
            this.game = game;
            this.upgradeMenu = upgradeMenu;
            upgradeMenu.visible = false;
            this.view = view;
            selectionBox = new Rectangle(-1, -1, 0, 0);
            selectionLine = selectRect;
            prevMs = Mouse.GetState();
            selectedCells = new List<GameboardCell>();
            isDragging = false;
        }

        /*private void setState(int state)
        {
            this.state = state;
        }*/

        

        public void setGameboard(GameboardComponent gameboard)
        {
            this.gameboard = gameboard;
        }

        public override void update()
        {
            foreach (ViewComponent vc in this.components)
            {
                vc.update();
            }

            mouseDrag();
        }

        public override void draw(SpriteBatch sb)
        {
            if (this.background != null)
            {
                sb.Begin();
                sb.Draw(background, new Rectangle(0, 0, 1025, 600), Color.White);
                sb.End();
            }
            foreach (ViewComponent vc in this.components)
            {
                vc.draw(sb);
            }

            gameboard.draw(sb);

            if (upgradeMenu.visible)
            {
                upgradeMenu.draw(sb);
            }

            sb.Begin();
            if (selectionBox.X != -1 && selectionBox.Y != -1)
            {
                //Draws the entire selection box area
                DrawHorizontalLine(selectionBox.Y, sb);
                DrawHorizontalLine(selectionBox.Y + selectionBox.Height, sb);
                DrawVerticalLine(selectionBox.X, sb);
                DrawVerticalLine(selectionBox.X + selectionBox.Width, sb);
            }
            sb.End();


        }

        #region Draw selection box helper methods
        private void DrawHorizontalLine(int posY, SpriteBatch sb)
        {
            //draws dotted line of 5 px moving right
            if (selectionBox.Width > 0)
            {
                for (int counter = 0; counter <= selectionBox.Width - 5; counter += 5)
                {
                    sb.Draw(selectionLine, new Rectangle(selectionBox.X + counter, posY, 5, 3), Color.White);
                }
            }
            //draws dotted line of 5 px moving left
            else if (selectionBox.Width < 0)
            {
                for (int counter = -5; counter >= selectionBox.Width; counter -= 5)
                {
                    if (selectionBox.Width - counter <= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(selectionBox.X + counter, posY, 5, 3), Color.White);
                    }
                }
            }
        }

        private void DrawVerticalLine(int posX, SpriteBatch sb)
        {
            if (selectionBox.Height > 0)
            {
                for (int counterY = 0; counterY <= selectionBox.Height; counterY += 5)
                {
                    //draws the dashed rectangle moving down, rotated 90 degrees
                    if (selectionBox.Height - counterY >= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(posX, selectionBox.Y + counterY, 5, 3),
                            new Rectangle(0, 0, selectionLine.Width, selectionLine.Height), Color.White, MathHelper.ToRadians(90), new Vector2(0, 0), SpriteEffects.None, 0);
                    }
                }
            }

            else if (selectionBox.Height < 0)
            {
                for (int counterY = 0; counterY >= selectionBox.Height; counterY -= 5)
                {
                    //draws rectangles moving up (bug with positioning)
                    if (selectionBox.Height - counterY <= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(posX, selectionBox.Y + counterY, 5, 3), Color.White);
                    }
                }
            }

        }
        #endregion

        #region Mouse Methods
        private void mouseDrag()
        {
            ms = Mouse.GetState();

            if (ms.LeftButton == ButtonState.Pressed && prevMs.LeftButton == ButtonState.Released)
            {
                selectionBox = new Rectangle(ms.X, ms.Y, 0, 0);
            }

            if (ms.LeftButton == ButtonState.Pressed)
            {
                selectionBox = new Rectangle(selectionBox.X, selectionBox.Y, ms.X - selectionBox.X, ms.Y - selectionBox.Y);
                isDragging = true;
            }

            else if (ms.LeftButton == ButtonState.Released)
            {
                if (isDragging)
                {
                    searchSelectRectangle(selectionBox);
                }

                selectionBox = new Rectangle(-1, -1, 0, 0);
                isDragging = false;
            }

            prevMs = ms;
        }

        public override void mouseOver(int x, int y)
        {
            if (upgradeMenu.visible)
            {
                upgradeMenu.mouseOver(x,y);
            }
            else
            {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mouseOver(x, y);
                }
                gameboard.mouseOver(x, y);
            }
        }

        public override void mousePressed(int x, int y)
        {
            if (upgradeMenu.visible)
            {
                upgradeMenu.mousePressed(x, y);
                if (!upgradeMenu.checkCollision(x, y))
                {
                    //upgradeMenu.visible = false;
                    //gameboard.mousePressed(x, y);
                    foreach (GameboardCell c in selectedCells)
                    {
                        c.setSelected(false);
                    }
                    selectedCells.Clear();
                }
            }
            else
            {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mousePressed(x, y);
                }
                gameboard.mousePressed(x, y);
                foreach (GameboardCell c in selectedCells)
                {
                    c.setSelected(false);
                }
                selectedCells.Clear();
            }
        }

        public override void mouseReleased(int x, int y)
        {

            if (!upgradeMenu.visible)
            {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mouseReleased(x, y);
                }
                gameboard.mouseReleased(x, y);
            }
        }
        #endregion

        /*public void showUpgradeMenu(GameboardCell target)
        {
            selectedTile = target.getTile();
            upgradeMenu.setLocation(target.getX()-upgradeMenu.getWidth()/2, target.getY()-upgradeMenu.getHeight());
            if (availableUpgrades != null)
            {
                upgradeMenu.setUpgradesActive(availableUpgrades);
                upgradeMenu.visible = true;
            }
        }*/

        public List<Tile> getSelectedTiles()
        {
            if (selectedCells.Count > 0)
            {
                return getTileList(selectedCells);
            }
            else
            {
                List<Tile> l = new List<Tile>();
                l.Add(selectedTile);
                return l;
            }
        }

/*        internal void setAvailableUpgrades(List<int> availableUpgrades)
        {
            this.availableUpgrades = availableUpgrades;
        }
        */
        internal void doMoveAndShowUpgradeMenu(GameboardCell target, Game game)
        {
            List<int> availableUpgrades;

            selectedTile = target.getTile();
            if (selectedCells.Count > 0)
            {
                List<Tile> selectedTiles = getTileList(selectedCells);
                target = selectedCells[0];
                selectedTile = selectedTiles[0];
                availableUpgrades = game.doMove(selectedTiles);
            }
            else
            {
                availableUpgrades = game.doMove(selectedTile);
            }
            upgradeMenu.setLocation(10 + target.getX() - upgradeMenu.getWidth() / 2, target.getY() - upgradeMenu.getHeight());
            if (availableUpgrades != null)
            {
                upgradeMenu.setUpgradesActive(availableUpgrades);
                upgradeMenu.visible = true;
            }
            else
            {
                upgradeMenu.setUpgradesActive(new List<int>());
            }
        }

        private List<Tile> getTileList(List<GameboardCell> selectedCells)
        {
            List<Tile> selectedTiles = new List<Tile>();
            foreach (GameboardCell c in selectedCells)
            {
                selectedTiles.Add(c.getTile());
            }

            return selectedTiles;
        }

        public void refreshAvailableUpgrades(List<int> upg)
        {
            if (upg != null)
            {
                upgradeMenu.setUpgradesActive(upg);
            }
        }

        public void searchSelectRectangle(Rectangle selection)
        {

            int offX = gameboard.getX();
            int offY = gameboard.getY();

            int gridTLX = selection.Left - offX;
            int gridTLY = selection.Top - offY;
            int gridBRX = selection.Right - offX;
            int gridBRY = selection.Bottom - offY;

            if (gridTLX > gridBRX)
            {
                int temp = gridTLX;
                gridTLX = gridBRX;
                gridBRX = temp;
            }

            if (gridTLY > gridBRY)
            {
                int temp = gridTLY;
                gridTLY = gridBRY;
                gridBRY = temp;
            }

            int cH = gameboard.getCellHeight();
            int cW = gameboard.getCellWidth();

            int cellTLX = gridTLX / cW;
            int cellTLY = gridTLY / cH;
            int cellBRX = gridBRX / cW;
            int cellBRY = gridBRY / cH;

            //int gridX = (selection.X + (selection.Width % gameboard.getCellWidth())) / gameboard.getCellWidth();
            //int gridY = (selection.Y + (selection.Height % gameboard.getCellHeight())) / gameboard.getCellHeight();

            //if tile is in selection area, add to selectedTiles list
            /*for (int i = gridX; i < (selection.Width / gameboard.getCellWidth()); i++)
            {
                for (int j = gridY; j < (selection.Height / gameboard.getCellHeight()); j++)
                {
                    //add checker for player cell
                    selectedCells.Add(gameboard.getCells()[i][j]);
                }
            }*/

            for (int j = cellTLX + 1; j < cellBRX; j++)
            {
                for (int i = cellTLY + 1; i < cellBRY; i++)
                {
                    //Tile cT = ((GameboardCell)gameboard.getCells()[i + 1][gameboard.getGame().board.getHeight() - (j + 1)]).getTile();
                    //if(cT.getVirus() != null)
                    //    view.getCurrentPlayer().alertViruses.Add(cT.getVirus());
                    //add checker for player cell
                    /*Jonathan change*/if(i >= 0 && j >= 0 && i < gameboard.getGame().board.getHeight() && j < gameboard.getGame().board.getWidth()
                        && ((GameboardCell)gameboard.getCells()[i][j]).getTile().getVirus() != null)
                    {
                        if( Virus.isFriend(view.getCurrentPlayerIndex(), (gameboard.getCells()[i][j]).getTile().getVirus()))
                        {
                            selectedCells.Add(gameboard.getCells()[i][j]);
                        }
                    }
                }
            }

            //mark for draw as selected
            foreach (GameboardCell sCell in selectedCells)
            {
                sCell.setSelected(true);
                System.Diagnostics.Debug.WriteLine(sCell.getTile());
            }

            if (selectedCells.Count > 0)
            {
                doMoveAndShowUpgradeMenu(selectedCells[0], game);
            }
        }




        public String getDataToDisplay()
        {
            return View.getHudText();
        }
    }
}
